package org.example.mppg.util;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.SneakyThrows;
import org.geotools.geojson.geom.GeometryJSON;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.Point;
import org.locationtech.jts.io.ParseException;
import org.locationtech.jts.io.WKTReader;
import org.locationtech.jts.io.WKTWriter;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;

/**
 * @description:
 * @author: bo
 * @create: 2024-09-24 18:08
 */
public class GeoJSONUtils {

    private static final WKTReader READER = new WKTReader();

    public static String converGemToGeoJSON(Geometry geometry) {
        String json = null;
        try {
            StringWriter writer = new StringWriter();
            //小数点后多少位
            GeometryJSON g = new GeometryJSON(7);
            g.write(geometry, writer);
            json = writer.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return json;
    }

    /**
     *  geoJson转wkt
     * @param jsonObject
     * @return
     */
    // public static String jsonToWkt(JSONObject jsonObject) {
    //     String wkt = null;
    //     String type = jsonObject.getString("type");
    //     GeometryJSON gJson = new GeometryJSON();
    //     try {
    //         // {"geometries":[{"coordinates":[4,6],"type":"Point"},{"coordinates":[[4,6],[7,10]],"type":"LineString"}],"type":"GeometryCollection"}
    //         if(GeoUtils.GEO_JSON_TYPE.equals(type)){
    //             // 由于解析上面的json语句会出现这个geometries属性没有采用以下办法
    //             JSONArray geometriesArray = jsonObject.getJSONArray("geometries");
    //             // 定义一个数组装图形对象
    //             int size = geometriesArray.size();
    //             Geometry[] geometries=new Geometry[size];
    //             for (int i=0;i<size;i++){
    //                 String str = geometriesArray.get(i).toString();
    //                 // 使用GeoUtil去读取str
    //                 Reader reader = GeoJSONUtil.toReader(str);
    //                 Geometry geometry = gJson.read(reader);
    //                 geometries[i]=geometry;
    //             }
    //             GeometryCollection geometryCollection = new GeometryCollection(geometries,new GeometryFactory());
    //             wkt=geometryCollection.toText();
    //         }else {
    //             Reader reader = GeoJSONUtil.toReader(jsonObject.toString());
    //             Geometry read = gJson.read(reader);
    //             wkt=read.toText();
    //         }
    //
    //     } catch (IOException e){
    //         System.out.println("GeoJson转WKT出现异常");
    //         e.printStackTrace();
    //     }
    //     return wkt;
    // }

    /**
     * 获取空间信息并构造为Map
     *
     * @param wkt
     * @return
     */
    public static Map getGeoMap(String wkt) {
        Map<String, Object> geoMap = new HashMap<>();
        String json = null;
        try {
            WKTReader reader = new WKTReader();
            Geometry geometry = reader.read(wkt);
            StringWriter writer = new StringWriter();
            GeometryJSON g = new GeometryJSON();
            g.write(geometry, writer);
            geoMap.put("geometry", writer);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return geoMap;
    }

    public static Geometry wkt2Geometry(String wktString) {
        GeometryFactory gc = JTSFactoryFinder.getGeometryFactory();
        WKTReader reader = new WKTReader(gc);
        Geometry geom = null;
        try {
            geom = reader.read(wktString);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return geom;
    }


    public static String geometry2Wkt(Geometry geometry) throws ParseException {
        WKTWriter writer = new WKTWriter();
        return writer.write(geometry);
    }


    /**
     * 序列化
     * WKTToGeoJSON
     *
     * @param wkt
     * @return
     */
    public static String convertWKTToGeoJSON(String wkt) {
        String json = null;
        try {
            WKTReader reader = new WKTReader();
            Geometry geometry = reader.read(wkt);
            StringWriter writer = new StringWriter();
            //小数点后多少位
            GeometryJSON g = new GeometryJSON(7);
            g.write(geometry, writer);
            json = writer.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return json;
    }

    @SneakyThrows
    public static Geometry geoJson2Geometry(String geoJson) {
        //GeometryJSON:Reads and writes geometry objects to and from geojson
        GeometryJSON geometryJSON = new GeometryJSON(7);
        return geometryJSON.read(new StringReader(geoJson));
    }


    @SneakyThrows
    public static Point geoJson2Point(String geoJson) {
        GeometryJSON qison = new GeometryJSON();
        Reader reader = new StringReader(geoJson);
        return qison.readPoint(reader);
    }


    /**
     * WKT 转 GeoJson
     *
     * @param wktStr WKT 字符串
     * @return GeoJson 对象
     */
    public static JSONObject wktToGeoJson(String wktStr) {
        JSONObject jsonObject = new JSONObject();
        try {
            Geometry geometry = READER.read(wktStr);
            StringWriter writer = new StringWriter();
            GeometryJSON geometryJson = new GeometryJSON();
            geometryJson.write(geometry, writer);
            jsonObject = JSONUtil.parseObj(writer.toString());
        } catch (Exception e) {
            System.out.println("WKT 转 GeoJson 出现异常：" + e);
            e.printStackTrace();
        }
        return jsonObject;
    }

    public static void main(String[] args) {
        String poly = "Polygon((1.0 1.0, 2.0 1.0, 2.0 2.0, 1.0 2.0, 1.0 1.0))";

        String wktString = "POINT (116.3840961495821 40.10829581003965)";
        Geometry geometry = wkt2Geometry(wktString);
        System.out.println("geometry = " + geometry.getGeometryType());

        Geometry geoms = wkt2Geometry(poly);
        System.out.println("geoms = " + geoms.getGeometryType());

        JSONObject jsonObject = wktToGeoJson(wktString);
        System.out.println("jsonObject = " + jsonObject);

        Point point = geoJson2Point(jsonObject.toString());
        System.out.println("point = " + point);


        //"0101000020E61000002C39382229FD5D4085716007088C3E40"

        String geojson = "{\"type\":\"Polygon\",\"coordinates\":[[[119.273071,33.093843],[119.273071,33.254767],[119.775696,33.254767],[119.775696,33.093843],[119.273071,33.093843]]]}";
        Geometry geometry1 = geoJson2Geometry(geojson);
        System.out.println("geometry1 = " + geometry1);

    }

    public void geojson2GeometryTest() throws IOException {
        String json1 = "{ \"type\": \"Polygon\", \"coordinates\": [ [ [ [ 114.318459657701752, 25.451711491442541 ], [ 114.338936430317901, 25.468215158924203 ], [ 114.365220048899801, 25.458129584352076 ], [ 114.377750611246995, 25.405562347188262 ], [ 114.322127139364355, 25.39822738386308 ], [ 114.318459657701752, 25.451711491442541 ] ] ] ] }";
    }
}
